Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc.
;; An example of using the "thread-last" macro to get ;; the sum of the first 10 even squares. user=> (->> (range) (map #(* % %)) (filter even?) (take 10) (reduce +)) 1140 ;; This expands to: user=> (reduce + (take 10 (filter even? (map #(* % %) (range))))) 1140
user=> (def c 5) user=> (->> c (+ 3) (/ 2) (- 1)) 3/4 ;; and if you are curious why user=> (use 'clojure.walk) user=> (macroexpand-all '(->> c (+ 3) (/ 2) (- 1))) (- 1 (/ 2 (+ 3 c)))
;; let's compare thread first (->) and thread last ( ->> ) user=> (macroexpand '(-> 0 (+ 1) (+ 2) (+ 3))) (+ (+ (+ 0 1) 2) 3) user=> (macroexpand '(->> 0 (+ 1) (+ 2) (+ 3))) (+ 3 (+ 2 (+ 1 0)))
;; ->> and -> by simple string concatenation ;; Effectively (str " jmd" "hello") user=> (->> "hello" (str " jmd")) " jmdhello" ;; Effectively (str "hello" " jmd") user=> (-> "hello" (str " jmd")) => "hello jmd"
;; It is OK to omit the parentheses if a function takes only one argument (->> [1 2 [3 4] 5] flatten ; no parenthesis (map inc)) => (2 3 4 5 6)
;; It's OK to include anonymous function in the thread, but don't forget ;; to put in an extra pair of parentheses to call the function (->> [1 2 3 4 5] ((fn [coll] (map inc coll))) ; double parentheses (apply +)) => 20 ;; the short hand form of the anonymous function works the same (->> [1 2 3 4 5] (#(map inc %)) ; double parentheses (apply +)) ;; avoid function (->> [1 2 3 4 5] (map inc) ; single parentheses (apply +))
;; For large threads you can use commas (interpreted as whitespaces) ;; to visualize where the items are going to be inserted. ;; Takes the first 5 even numbers user=> (->> (range) (filter even?) (take 5)) => (0 2 4 6 8) ;; with two commas (you can use one if you prefer) user=> (->> (range) (filter even? ,,) (take 5 ,,)) => (0 2 4 6 8) ;; For instance: ;; (filter even? ,,) ;; means ;; (filter even? (range))
;;practical example (def entries [{:month 1 :val 12} {:month 2 :val 3} {:month 3 :val 32} {:month 4 :val 18} {:month 5 :val 32} {:month 6 :val 62} {:month 7 :val 12} {:month 8 :val 142} {:month 9 :val 52} {:month 10 :val 18} {:month 11 :val 23} {:month 12 :val 56}]) (defn get-result [coll m] (->> coll (take-while #(<= (:month %) m)))) (defn get-total [coll m] (->> (get-result coll m) (map #(:val %)) (reduce +))) (get-total entries 3)
(defn new-map [coll] (->> coll (map (fn [[k v]] [k (inc v)])) (into {}))) (new-map {:a 1 :b 2 :c 3})
(defn f [front a1 a2 end] (str front "-" a1 "-" a2 "-" end)) (println (f 1 2 3 4)) ;; => 1-2-3-4 (println (-> 1 (f 2 3 4))) ;; => 1-2-3-4 (println (->> 1 (f 2 3 4))) ;; => 2-3-4-1
Threads the expr through the forms. Inserts x as the second item in the first form, making a list ...
When expr is not nil, threads it into the first form (via ->>), and when that result is not nil, t...
Takes a set of functions and returns a fn that is the composition of those fns. The returned fn t...
Takes an expression and a set of test/form pairs. Threads expr (via ->>) through each form for whi...
Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for whic...
Binds name to expr, evaluates the first form in the lexical context of that binding, then binds na...
I'm getting: Exception in thread "main" java.lang.Exception: Unable to resolve symbol: ->> in this context (11.clj:25)
It's also extremely hard to Google this method. It'd be nice if there was a non-symbol name for this that one could search for.
Update
The name of this operator is called a thrush.
See also -> which is similar but threads the first expr as the second argument of the forms.
There is something I don't get : in the case "form" is a seq, why should we write ... (with-meta `(~(first form) ~@(next form) ~x) (meta form))
and not ... (with-meta `(~@form ~x) (meta form))
as items order in "form" is not changed ?